Enter the directory of the maca folder on your drive and the name of the tissue you want to analyze.

tissue_of_interest = "Tongue"

Load the requisite packages and some additional helper functions.

library(here)
library(useful)
library(Seurat)
library(dplyr)
library(Matrix)
library(ontologyIndex)
cell_ontology = get_ontology('https://raw.githubusercontent.com/obophenotype/cell-ontology/master/cl-basic.obo', extract_tags='everything')
validate_cell_ontology = function(cell_ontology_class){
  in_cell_ontology = sapply(cell_ontology_class, function(x) is.element(x, cell_ontology$name))
  if (!all(in_cell_ontology)) {
    message = paste0('"', cell_ontology_class[!in_cell_ontology], '" is not in the cell ontology
')
    stop(message)
  }
}
convert_to_cell_ontology_id = function(cell_ontology_class){
  return(sapply(cell_ontology_class, function(x) as.vector(cell_ontology$id[cell_ontology$name == x])[1]))
}
save_dir = here('00_data_ingest', 'tissue_robj')
# read the metadata to get the plates we want
plate_metadata_filename = here('00_data_ingest', '00_facs_raw_data', 'metadata_FACS.csv')
plate_metadata <- read.csv(plate_metadata_filename, sep=",", header = TRUE)
colnames(plate_metadata)[1] <- "plate.barcode"
plate_metadata

Subset the metadata on the tissue.

tissue_plates = filter(plate_metadata, tissue == tissue_of_interest)[,c('plate.barcode','tissue','subtissue','mouse.sex', 'mouse.id')]
tissue_plates

Load the read count data.

#Load the gene names and set the metadata columns by opening the first file
filename = here('00_data_ingest', '00_facs_raw_data', 'FACS', paste0(tissue_of_interest, '-counts.csv'))
raw.data = read.csv(filename, sep=",", row.names=1)
# raw.data = data.frame(row.names = rownames(raw.data))
corner(raw.data)

Make a vector of plate barcodes for each cell

plate.barcodes = lapply(colnames(raw.data), function(x) strsplit(strsplit(x, "_")[[1]][1], '.', fixed=TRUE)[[1]][2])
head(plate.barcodes)
[[1]]
[1] "D041894"

[[2]]
[1] "D041894"

[[3]]
[1] "D041894"

[[4]]
[1] "D041894"

[[5]]
[1] "D041894"

[[6]]
[1] "D041894"

Use only the metadata rows corresponding to Bladder plates. Make a plate barcode dataframe to “expand” the per-plate metadata to be per-cell.

barcode.df = t.data.frame(as.data.frame(plate.barcodes))
rownames(barcode.df) = colnames(raw.data)
colnames(barcode.df) = c('plate.barcode')
head(barcode.df)
                      plate.barcode
A15.D041894.3_9_M.1.1 "D041894"    
B19.D041894.3_9_M.1.1 "D041894"    
C21.D041894.3_9_M.1.1 "D041894"    
E1.D041894.3_9_M.1.1  "D041894"    
F4.D041894.3_9_M.1.1  "D041894"    
G7.D041894.3_9_M.1.1  "D041894"    
rnames = row.names(barcode.df)
meta.data <- merge(barcode.df, plate_metadata, by='plate.barcode', sort = F)
row.names(meta.data) <- rnames
# Sort cells by plate barcode because that's how the data was originally
meta.data = meta.data[order(meta.data$plate.barcode), ]
corner(meta.data)
raw.data = raw.data[, rownames(meta.data)]
corner(raw.data)

Process the raw data and load it into the Seurat object.

# Find ERCC's, compute the percent ERCC, and drop them from the raw data.
erccs <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = TRUE)
percent.ercc <- Matrix::colSums(raw.data[erccs, ])/Matrix::colSums(raw.data)
ercc.index <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = FALSE)
raw.data <- raw.data[-ercc.index,]
# Create the Seurat object with all the data
tiss <- CreateSeuratObject(raw.data = raw.data, project = tissue_of_interest, 
                    min.cells = 5, min.genes = 5)
tiss <- AddMetaData(object = tiss, meta.data)
tiss <- AddMetaData(object = tiss, percent.ercc, col.name = "percent.ercc")
# Change default name for sums of counts from nUMI to nReads
colnames(tiss@meta.data)[colnames(tiss@meta.data) == 'nUMI'] <- 'nReads'
# Create metadata columns for cell_ontology_classs and subcell_ontology_classs
tiss@meta.data[,'cell_ontology_class'] <- NA
tiss@meta.data[,'subcell_ontology_class'] <- NA

Calculate percent ribosomal genes.

ribo.genes <- grep(pattern = "^Rp[sl][[:digit:]]", x = rownames(x = tiss@data), value = TRUE)
percent.ribo <- Matrix::colSums(tiss@raw.data[ribo.genes, ])/Matrix::colSums(tiss@raw.data)
tiss <- AddMetaData(object = tiss, metadata = percent.ribo, col.name = "percent.ribo")

A sanity check: genes per cell vs reads per cell.

GenePlot(object = tiss, gene1 = "nReads", gene2 = "nGene", use.raw=T)

Filter out cells with few reads and few genes.

tiss <- FilterCells(object = tiss, subset.names = c("nGene", "nReads"), 
    low.thresholds = c(500, 50000), high.thresholds = c(25000, 2000000))

Normalize the data, then regress out correlation with total reads

tiss <- NormalizeData(object = tiss, scale.factor = 1e6)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
tiss <- ScaleData(object = tiss)
[1] "Scaling data matrix"

  |                                                                                                                                                     
  |                                                                                                                                               |   0%
  |                                                                                                                                                     
  |===============================================================================================================================================| 100%
tiss <- FindVariableGenes(object = tiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.5)
Calculating gene means
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating gene variance to mean ratios
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

Run Principal Component Analysis.

tiss <- RunPCA(object = tiss, do.print = FALSE)
tiss <- ProjectPCA(object = tiss, do.print = FALSE)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

PCElbowPlot(object = tiss)

Choose the number of principal components to use.

# Set number of principal components. 
n.pcs = 10

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

For the top-level clustering, aim to under-cluster instead of over-cluster. It will be easy to subset groups and further analyze them below.

# Set resolution 
res.used <- 0.7
tiss <- FindClusters(object = tiss, reduction.type = "pca", dims.use = 1:n.pcs, 
    resolution = res.used, print.output = 0, save.SNN = TRUE, force.recalc = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
tiss <- RunTSNE(object = tiss, dims.use = 1:n.pcs, seed.use = 20, perplexity=40)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = tiss, do.label = T, pt.size = 1.2, label.size = 4)

Check expression of genes of interset.

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

How big are the clusters?

table(tiss@ident)

  0   1   2   3   4   5   6   7 
391 253 194 178 162 123  68  25 
tiss1=BuildClusterTree(tiss)
[1] "Finished averaging RNA for cluster 0"
[1] "Finished averaging RNA for cluster 1"
[1] "Finished averaging RNA for cluster 2"
[1] "Finished averaging RNA for cluster 3"
[1] "Finished averaging RNA for cluster 4"
[1] "Finished averaging RNA for cluster 5"
[1] "Finished averaging RNA for cluster 6"
[1] "Finished averaging RNA for cluster 7"

Which markers identify a specific cluster?

#cluster1.markers <- FindMarkers(object = tiss, ident.1 = 1, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster2.markers <- FindMarkers(object = tiss, ident.1 = 2, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster3.markers <- FindMarkers(object = tiss, ident.1 = 3, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster4.markers <- FindMarkers(object = tiss, ident.1 = 4, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster5.markers <- FindMarkers(object = tiss, ident.1 = 5, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
#cluster6.markers <- FindMarkers(object = tiss, ident.1 = 6, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
cluster7.markers <- FindMarkers(object = tiss, ident.1 = 6, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 58s      
   |++                                                | 2 % ~02m 53s      
   |++                                                | 3 % ~02m 30s      
   |+++                                               | 4 % ~02m 14s      
   |+++                                               | 5 % ~02m 06s      
   |++++                                              | 6 % ~02m 03s      
   |++++                                              | 7 % ~01m 59s      
   |+++++                                             | 8 % ~01m 56s      
   |+++++                                             | 9 % ~01m 51s      
   |++++++                                            | 10% ~01m 48s      
   |++++++                                            | 11% ~01m 46s      
   |+++++++                                           | 12% ~01m 43s      
   |+++++++                                           | 13% ~01m 41s      
   |++++++++                                          | 14% ~01m 38s      
   |++++++++                                          | 15% ~01m 36s      
   |+++++++++                                         | 16% ~01m 34s      
   |+++++++++                                         | 17% ~01m 32s      
   |++++++++++                                        | 18% ~01m 31s      
   |++++++++++                                        | 19% ~01m 29s      
   |+++++++++++                                       | 20% ~01m 28s      
   |+++++++++++                                       | 21% ~01m 26s      
   |++++++++++++                                      | 22% ~01m 25s      
   |++++++++++++                                      | 23% ~01m 24s      
   |+++++++++++++                                     | 24% ~01m 22s      
   |+++++++++++++                                     | 26% ~01m 21s      
   |++++++++++++++                                    | 27% ~01m 19s      
   |++++++++++++++                                    | 28% ~01m 18s      
   |+++++++++++++++                                   | 29% ~01m 17s      
   |+++++++++++++++                                   | 30% ~01m 16s      
   |++++++++++++++++                                  | 31% ~01m 14s      
   |++++++++++++++++                                  | 32% ~01m 13s      
   |+++++++++++++++++                                 | 33% ~01m 12s      
   |+++++++++++++++++                                 | 34% ~01m 11s      
   |++++++++++++++++++                                | 35% ~01m 09s      
   |++++++++++++++++++                                | 36% ~01m 08s      
   |+++++++++++++++++++                               | 37% ~01m 07s      
   |+++++++++++++++++++                               | 38% ~01m 06s      
   |++++++++++++++++++++                              | 39% ~01m 05s      
   |++++++++++++++++++++                              | 40% ~01m 04s      
   |+++++++++++++++++++++                             | 41% ~01m 02s      
   |+++++++++++++++++++++                             | 42% ~01m 01s      
   |++++++++++++++++++++++                            | 43% ~01m 00s      
   |++++++++++++++++++++++                            | 44% ~59s          
   |+++++++++++++++++++++++                           | 45% ~58s          
   |+++++++++++++++++++++++                           | 46% ~57s          
   |++++++++++++++++++++++++                          | 47% ~56s          
   |++++++++++++++++++++++++                          | 48% ~54s          
   |+++++++++++++++++++++++++                         | 49% ~54s          
   |+++++++++++++++++++++++++                         | 50% ~52s          
   |++++++++++++++++++++++++++                        | 51% ~51s          
   |+++++++++++++++++++++++++++                       | 52% ~50s          
   |+++++++++++++++++++++++++++                       | 53% ~49s          
   |++++++++++++++++++++++++++++                      | 54% ~48s          
   |++++++++++++++++++++++++++++                      | 55% ~47s          
   |+++++++++++++++++++++++++++++                     | 56% ~46s          
   |+++++++++++++++++++++++++++++                     | 57% ~45s          
   |++++++++++++++++++++++++++++++                    | 58% ~44s          
   |++++++++++++++++++++++++++++++                    | 59% ~42s          
   |+++++++++++++++++++++++++++++++                   | 60% ~41s          
   |+++++++++++++++++++++++++++++++                   | 61% ~40s          
   |++++++++++++++++++++++++++++++++                  | 62% ~39s          
   |++++++++++++++++++++++++++++++++                  | 63% ~39s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~37s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~36s          
   |++++++++++++++++++++++++++++++++++                | 66% ~35s          
   |++++++++++++++++++++++++++++++++++                | 67% ~34s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~33s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~32s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~31s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~30s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~29s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~28s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~26s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~25s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~24s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~23s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~22s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~21s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~20s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~19s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~18s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 41s
#cluster0.markers <- FindMarkers(object = tiss, ident.1 = 0, min.pct = 0.25, only.pos = TRUE, thresh.use = 0.25)
print(x = head(x = cluster6.markers, n = 30))

You can also compute all markers for all clusters at once. This may take some time.

tiss.markers <- FindAllMarkers(object = tiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 25s      
   |++                                                | 2 % ~01m 22s      
   |++                                                | 3 % ~01m 22s      
   |+++                                               | 4 % ~01m 23s      
   |+++                                               | 5 % ~01m 21s      
   |++++                                              | 6 % ~01m 20s      
   |++++                                              | 7 % ~01m 19s      
   |+++++                                             | 8 % ~01m 18s      
   |+++++                                             | 9 % ~01m 17s      
   |++++++                                            | 10% ~01m 16s      
   |++++++                                            | 11% ~01m 15s      
   |+++++++                                           | 12% ~01m 15s      
   |+++++++                                           | 13% ~01m 14s      
   |++++++++                                          | 14% ~01m 13s      
   |++++++++                                          | 15% ~01m 12s      
   |+++++++++                                         | 16% ~01m 11s      
   |+++++++++                                         | 17% ~01m 10s      
   |++++++++++                                        | 18% ~01m 09s      
   |++++++++++                                        | 19% ~01m 08s      
   |+++++++++++                                       | 20% ~01m 08s      
   |+++++++++++                                       | 21% ~01m 07s      
   |++++++++++++                                      | 22% ~01m 06s      
   |++++++++++++                                      | 23% ~01m 05s      
   |+++++++++++++                                     | 24% ~01m 04s      
   |+++++++++++++                                     | 26% ~01m 03s      
   |++++++++++++++                                    | 27% ~01m 02s      
   |++++++++++++++                                    | 28% ~01m 02s      
   |+++++++++++++++                                   | 29% ~01m 01s      
   |+++++++++++++++                                   | 30% ~60s          
   |++++++++++++++++                                  | 31% ~59s          
   |++++++++++++++++                                  | 32% ~58s          
   |+++++++++++++++++                                 | 33% ~57s          
   |+++++++++++++++++                                 | 34% ~56s          
   |++++++++++++++++++                                | 35% ~56s          
   |++++++++++++++++++                                | 36% ~55s          
   |+++++++++++++++++++                               | 37% ~54s          
   |+++++++++++++++++++                               | 38% ~53s          
   |++++++++++++++++++++                              | 39% ~52s          
   |++++++++++++++++++++                              | 40% ~51s          
   |+++++++++++++++++++++                             | 41% ~50s          
   |+++++++++++++++++++++                             | 42% ~50s          
   |++++++++++++++++++++++                            | 43% ~49s          
   |++++++++++++++++++++++                            | 44% ~48s          
   |+++++++++++++++++++++++                           | 45% ~47s          
   |+++++++++++++++++++++++                           | 46% ~46s          
   |++++++++++++++++++++++++                          | 47% ~46s          
   |++++++++++++++++++++++++                          | 48% ~45s          
   |+++++++++++++++++++++++++                         | 49% ~44s          
   |+++++++++++++++++++++++++                         | 50% ~43s          
   |++++++++++++++++++++++++++                        | 51% ~42s          
   |+++++++++++++++++++++++++++                       | 52% ~41s          
   |+++++++++++++++++++++++++++                       | 53% ~41s          
   |++++++++++++++++++++++++++++                      | 54% ~40s          
   |++++++++++++++++++++++++++++                      | 55% ~39s          
   |+++++++++++++++++++++++++++++                     | 56% ~38s          
   |+++++++++++++++++++++++++++++                     | 57% ~37s          
   |++++++++++++++++++++++++++++++                    | 58% ~36s          
   |++++++++++++++++++++++++++++++                    | 59% ~35s          
   |+++++++++++++++++++++++++++++++                   | 60% ~34s          
   |+++++++++++++++++++++++++++++++                   | 61% ~33s          
   |++++++++++++++++++++++++++++++++                  | 62% ~33s          
   |++++++++++++++++++++++++++++++++                  | 63% ~32s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~31s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~30s          
   |++++++++++++++++++++++++++++++++++                | 66% ~29s          
   |++++++++++++++++++++++++++++++++++                | 67% ~28s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~27s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~26s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~26s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~25s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~23s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~22s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~21s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~21s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~20s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~19s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 27s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 40s      
   |++                                                | 2 % ~01m 38s      
   |++                                                | 3 % ~01m 36s      
   |+++                                               | 4 % ~01m 36s      
   |+++                                               | 5 % ~01m 39s      
   |++++                                              | 6 % ~01m 37s      
   |++++                                              | 7 % ~01m 35s      
   |+++++                                             | 8 % ~01m 34s      
   |+++++                                             | 9 % ~01m 32s      
   |++++++                                            | 10% ~01m 31s      
   |++++++                                            | 11% ~01m 30s      
   |+++++++                                           | 12% ~01m 29s      
   |+++++++                                           | 13% ~01m 28s      
   |++++++++                                          | 14% ~01m 27s      
   |++++++++                                          | 15% ~01m 26s      
   |+++++++++                                         | 16% ~01m 25s      
   |+++++++++                                         | 17% ~01m 24s      
   |++++++++++                                        | 18% ~01m 23s      
   |++++++++++                                        | 19% ~01m 22s      
   |+++++++++++                                       | 20% ~01m 21s      
   |+++++++++++                                       | 21% ~01m 20s      
   |++++++++++++                                      | 22% ~01m 19s      
   |++++++++++++                                      | 23% ~01m 18s      
   |+++++++++++++                                     | 24% ~01m 17s      
   |+++++++++++++                                     | 26% ~01m 16s      
   |++++++++++++++                                    | 27% ~01m 15s      
   |++++++++++++++                                    | 28% ~01m 14s      
   |+++++++++++++++                                   | 29% ~01m 13s      
   |+++++++++++++++                                   | 30% ~01m 12s      
   |++++++++++++++++                                  | 31% ~01m 10s      
   |++++++++++++++++                                  | 32% ~01m 09s      
   |+++++++++++++++++                                 | 33% ~01m 08s      
   |+++++++++++++++++                                 | 34% ~01m 07s      
   |++++++++++++++++++                                | 35% ~01m 06s      
   |++++++++++++++++++                                | 36% ~01m 05s      
   |+++++++++++++++++++                               | 37% ~01m 04s      
   |+++++++++++++++++++                               | 38% ~01m 03s      
   |++++++++++++++++++++                              | 39% ~01m 02s      
   |++++++++++++++++++++                              | 40% ~01m 01s      
   |+++++++++++++++++++++                             | 41% ~01m 00s      
   |+++++++++++++++++++++                             | 42% ~59s          
   |++++++++++++++++++++++                            | 43% ~58s          
   |++++++++++++++++++++++                            | 44% ~57s          
   |+++++++++++++++++++++++                           | 45% ~56s          
   |+++++++++++++++++++++++                           | 46% ~55s          
   |++++++++++++++++++++++++                          | 47% ~54s          
   |++++++++++++++++++++++++                          | 48% ~53s          
   |+++++++++++++++++++++++++                         | 49% ~52s          
   |+++++++++++++++++++++++++                         | 50% ~51s          
   |++++++++++++++++++++++++++                        | 51% ~50s          
   |+++++++++++++++++++++++++++                       | 52% ~49s          
   |+++++++++++++++++++++++++++                       | 53% ~48s          
   |++++++++++++++++++++++++++++                      | 54% ~47s          
   |++++++++++++++++++++++++++++                      | 55% ~46s          
   |+++++++++++++++++++++++++++++                     | 56% ~45s          
   |+++++++++++++++++++++++++++++                     | 57% ~44s          
   |++++++++++++++++++++++++++++++                    | 58% ~43s          
   |++++++++++++++++++++++++++++++                    | 59% ~42s          
   |+++++++++++++++++++++++++++++++                   | 60% ~41s          
   |+++++++++++++++++++++++++++++++                   | 61% ~40s          
   |++++++++++++++++++++++++++++++++                  | 62% ~39s          
   |++++++++++++++++++++++++++++++++                  | 63% ~38s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~37s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~36s          
   |++++++++++++++++++++++++++++++++++                | 66% ~35s          
   |++++++++++++++++++++++++++++++++++                | 67% ~34s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~32s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~31s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~30s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~29s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~28s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~27s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~26s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~25s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~24s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~23s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~22s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~21s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~20s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~19s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~18s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 42s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~03m 08s      
   |+                                                 | 2 % ~02m 47s      
   |++                                                | 3 % ~02m 39s      
   |++                                                | 4 % ~02m 34s      
   |+++                                               | 5 % ~02m 31s      
   |+++                                               | 6 % ~02m 29s      
   |++++                                              | 7 % ~02m 27s      
   |++++                                              | 8 % ~02m 25s      
   |+++++                                             | 9 % ~02m 23s      
   |+++++                                             | 10% ~02m 22s      
   |++++++                                            | 11% ~02m 20s      
   |++++++                                            | 12% ~02m 18s      
   |+++++++                                           | 13% ~02m 19s      
   |+++++++                                           | 14% ~02m 17s      
   |++++++++                                          | 15% ~02m 16s      
   |++++++++                                          | 16% ~02m 14s      
   |+++++++++                                         | 17% ~02m 11s      
   |+++++++++                                         | 18% ~02m 10s      
   |++++++++++                                        | 19% ~02m 08s      
   |++++++++++                                        | 20% ~02m 06s      
   |+++++++++++                                       | 21% ~02m 05s      
   |+++++++++++                                       | 22% ~02m 03s      
   |++++++++++++                                      | 23% ~02m 01s      
   |++++++++++++                                      | 24% ~01m 60s      
   |+++++++++++++                                     | 25% ~01m 58s      
   |+++++++++++++                                     | 26% ~01m 57s      
   |++++++++++++++                                    | 27% ~01m 55s      
   |++++++++++++++                                    | 28% ~01m 53s      
   |+++++++++++++++                                   | 29% ~01m 52s      
   |+++++++++++++++                                   | 30% ~01m 50s      
   |++++++++++++++++                                  | 31% ~01m 49s      
   |++++++++++++++++                                  | 32% ~01m 47s      
   |+++++++++++++++++                                 | 33% ~01m 45s      
   |+++++++++++++++++                                | 34% ~01m 44s      
   |++++++++++++++++++                                | 35% ~01m 42s      
   |++++++++++++++++++                                | 36% ~01m 42s      
   |+++++++++++++++++++                               | 37% ~01m 40s      
   |+++++++++++++++++++                               | 38% ~01m 38s      
   |++++++++++++++++++++                              | 39% ~01m 37s      
   |++++++++++++++++++++                              | 40% ~01m 35s      
   |+++++++++++++++++++++                             | 41% ~01m 33s      
   |+++++++++++++++++++++                             | 42% ~01m 32s      
   |++++++++++++++++++++++                            | 43% ~01m 30s      
   |++++++++++++++++++++++                            | 44% ~01m 28s      
   |+++++++++++++++++++++++                           | 45% ~01m 27s      
   |+++++++++++++++++++++++                           | 46% ~01m 25s      
   |++++++++++++++++++++++++                          | 47% ~01m 23s      
   |++++++++++++++++++++++++                          | 48% ~01m 22s      
   |+++++++++++++++++++++++++                         | 49% ~01m 20s      
   |+++++++++++++++++++++++++                         | 50% ~01m 19s      
   |++++++++++++++++++++++++++                        | 51% ~01m 17s      
   |++++++++++++++++++++++++++                        | 52% ~01m 15s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 14s      
   |+++++++++++++++++++++++++++                       | 54% ~01m 12s      
   |++++++++++++++++++++++++++++                      | 55% ~01m 10s      
   |++++++++++++++++++++++++++++                     | 56% ~01m 09s      
   |+++++++++++++++++++++++++++++                     | 57% ~01m 07s      
   |+++++++++++++++++++++++++++++                     | 58% ~01m 06s      
   |++++++++++++++++++++++++++++++                    | 59% ~01m 04s      
   |++++++++++++++++++++++++++++++                    | 60% ~01m 03s      
   |+++++++++++++++++++++++++++++++                   | 61% ~01m 01s      
   |+++++++++++++++++++++++++++++++                   | 62% ~59s          
   |++++++++++++++++++++++++++++++++                  | 63% ~58s          
   |++++++++++++++++++++++++++++++++                  | 64% ~56s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~55s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~53s          
   |++++++++++++++++++++++++++++++++++                | 67% ~51s          
   |++++++++++++++++++++++++++++++++++               | 68% ~50s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~48s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~47s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~45s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~44s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~42s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~41s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~39s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~37s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~36s          
   |+++++++++++++++++++++++++++++++++++++++          | 78% ~34s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~33s          
   |++++++++++++++++++++++++++++++++++++++++         | 80% ~31s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~30s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~28s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~27s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~25s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~23s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~22s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~19s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++++++    | 90% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~03s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02m 36s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~02m 10s      
   |++                                                | 2 % ~02m 05s      
   |++                                                | 3 % ~02m 02s      
   |+++                                               | 4 % ~01m 59s      
   |+++                                               | 5 % ~01m 58s      
   |++++                                              | 6 % ~01m 59s      
   |++++                                              | 7 % ~01m 57s      
   |+++++                                             | 8 % ~01m 55s      
   |+++++                                             | 9 % ~01m 55s      
   |++++++                                            | 10% ~01m 53s      
   |++++++                                            | 11% ~01m 52s      
   |+++++++                                           | 12% ~01m 50s      
   |+++++++                                           | 13% ~01m 49s      
   |++++++++                                          | 14% ~01m 48s      
   |++++++++                                          | 15% ~01m 46s      
   |+++++++++                                         | 16% ~01m 45s      
   |+++++++++                                         | 17% ~01m 44s      
   |++++++++++                                        | 18% ~01m 42s      
   |++++++++++                                        | 19% ~01m 41s      
   |+++++++++++                                       | 20% ~01m 40s      
   |+++++++++++                                       | 21% ~01m 38s      
   |++++++++++++                                      | 22% ~01m 37s      
   |++++++++++++                                      | 23% ~01m 36s      
   |+++++++++++++                                     | 24% ~01m 35s      
   |+++++++++++++                                     | 26% ~01m 34s      
   |++++++++++++++                                    | 27% ~01m 33s      
   |++++++++++++++                                    | 28% ~01m 31s      
   |+++++++++++++++                                   | 29% ~01m 30s      
   |+++++++++++++++                                   | 30% ~01m 29s      
   |++++++++++++++++                                  | 31% ~01m 28s      
   |++++++++++++++++                                  | 32% ~01m 26s      
   |+++++++++++++++++                                 | 33% ~01m 25s      
   |+++++++++++++++++                                 | 34% ~01m 24s      
   |++++++++++++++++++                                | 35% ~01m 22s      
   |++++++++++++++++++                                | 36% ~01m 21s      
   |+++++++++++++++++++                               | 37% ~01m 20s      
   |+++++++++++++++++++                               | 38% ~01m 19s      
   |++++++++++++++++++++                              | 39% ~01m 17s      
   |++++++++++++++++++++                              | 40% ~01m 16s      
   |+++++++++++++++++++++                             | 41% ~01m 15s      
   |+++++++++++++++++++++                             | 42% ~01m 14s      
   |++++++++++++++++++++++                            | 43% ~01m 12s      
   |++++++++++++++++++++++                            | 44% ~01m 11s      
   |+++++++++++++++++++++++                           | 45% ~01m 10s      
   |+++++++++++++++++++++++                           | 46% ~01m 09s      
   |++++++++++++++++++++++++                          | 47% ~01m 07s      
   |++++++++++++++++++++++++                          | 48% ~01m 06s      
   |+++++++++++++++++++++++++                         | 49% ~01m 05s      
   |+++++++++++++++++++++++++                         | 50% ~01m 03s      
   |++++++++++++++++++++++++++                        | 51% ~01m 02s      
   |+++++++++++++++++++++++++++                       | 52% ~01m 01s      
   |+++++++++++++++++++++++++++                       | 53% ~60s          
   |++++++++++++++++++++++++++++                      | 54% ~58s          
   |++++++++++++++++++++++++++++                      | 55% ~57s          
   |+++++++++++++++++++++++++++++                     | 56% ~56s          
   |+++++++++++++++++++++++++++++                     | 57% ~54s          
   |++++++++++++++++++++++++++++++                    | 58% ~53s          
   |++++++++++++++++++++++++++++++                    | 59% ~52s          
   |+++++++++++++++++++++++++++++++                   | 60% ~50s          
   |+++++++++++++++++++++++++++++++                   | 61% ~49s          
   |++++++++++++++++++++++++++++++++                  | 62% ~48s          
   |++++++++++++++++++++++++++++++++                  | 63% ~47s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~46s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~44s          
   |++++++++++++++++++++++++++++++++++                | 66% ~43s          
   |++++++++++++++++++++++++++++++++++                | 67% ~42s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~40s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~39s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~38s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~36s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~35s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~34s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~32s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~31s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~30s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~29s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~27s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~26s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~25s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~23s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~22s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~21s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~19s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~18s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~17s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~03s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02m 07s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 43s      
   |+                                                 | 2 % ~01m 42s      
   |++                                                | 3 % ~01m 41s      
   |++                                                | 4 % ~01m 39s      
   |+++                                               | 5 % ~01m 38s      
   |+++                                               | 6 % ~01m 38s      
   |++++                                              | 7 % ~01m 37s      
   |++++                                              | 8 % ~01m 36s      
   |+++++                                             | 9 % ~01m 37s      
   |+++++                                             | 10% ~01m 36s      
   |++++++                                            | 11% ~01m 35s      
   |++++++                                            | 12% ~01m 34s      
   |+++++++                                           | 13% ~01m 33s      
   |+++++++                                           | 14% ~01m 32s      
   |++++++++                                          | 15% ~01m 30s      
   |++++++++                                          | 16% ~01m 30s      
   |+++++++++                                         | 17% ~01m 29s      
   |+++++++++                                         | 18% ~01m 28s      
   |++++++++++                                        | 19% ~01m 31s      
   |++++++++++                                        | 20% ~01m 30s      
   |+++++++++++                                       | 21% ~01m 29s      
   |+++++++++++                                       | 22% ~01m 27s      
   |++++++++++++                                      | 23% ~01m 26s      
   |++++++++++++                                      | 24% ~01m 25s      
   |+++++++++++++                                     | 25% ~01m 24s      
   |+++++++++++++                                     | 26% ~01m 22s      
   |++++++++++++++                                    | 27% ~01m 21s      
   |++++++++++++++                                    | 28% ~01m 20s      
   |+++++++++++++++                                   | 29% ~01m 19s      
   |+++++++++++++++                                   | 30% ~01m 17s      
   |++++++++++++++++                                  | 31% ~01m 16s      
   |++++++++++++++++                                  | 32% ~01m 15s      
   |+++++++++++++++++                                 | 33% ~01m 14s      
   |+++++++++++++++++                                | 34% ~01m 13s      
   |++++++++++++++++++                                | 35% ~01m 12s      
   |++++++++++++++++++                                | 36% ~01m 12s      
   |+++++++++++++++++++                               | 37% ~01m 11s      
   |+++++++++++++++++++                               | 38% ~01m 09s      
   |++++++++++++++++++++                              | 39% ~01m 08s      
   |++++++++++++++++++++                              | 40% ~01m 07s      
   |+++++++++++++++++++++                             | 41% ~01m 06s      
   |+++++++++++++++++++++                             | 42% ~01m 05s      
   |++++++++++++++++++++++                            | 43% ~01m 04s      
   |++++++++++++++++++++++                            | 44% ~01m 02s      
   |+++++++++++++++++++++++                           | 45% ~01m 01s      
   |+++++++++++++++++++++++                           | 46% ~01m 00s      
   |++++++++++++++++++++++++                          | 47% ~59s          
   |++++++++++++++++++++++++                          | 48% ~58s          
   |+++++++++++++++++++++++++                         | 49% ~57s          
   |+++++++++++++++++++++++++                         | 50% ~55s          
   |++++++++++++++++++++++++++                        | 51% ~54s          
   |++++++++++++++++++++++++++                        | 52% ~53s          
   |+++++++++++++++++++++++++++                       | 53% ~52s          
   |+++++++++++++++++++++++++++                       | 54% ~51s          
   |++++++++++++++++++++++++++++                      | 55% ~50s          
   |++++++++++++++++++++++++++++                     | 56% ~49s          
   |+++++++++++++++++++++++++++++                     | 57% ~48s          
   |+++++++++++++++++++++++++++++                     | 58% ~46s          
   |++++++++++++++++++++++++++++++                    | 59% ~45s          
   |++++++++++++++++++++++++++++++                    | 60% ~44s          
   |+++++++++++++++++++++++++++++++                   | 61% ~43s          
   |+++++++++++++++++++++++++++++++                   | 62% ~42s          
   |++++++++++++++++++++++++++++++++                  | 63% ~41s          
   |++++++++++++++++++++++++++++++++                  | 64% ~40s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~39s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~38s          
   |++++++++++++++++++++++++++++++++++                | 67% ~37s          
   |++++++++++++++++++++++++++++++++++               | 68% ~35s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~34s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~33s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~32s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~31s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~30s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~29s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~28s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~26s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~25s          
   |+++++++++++++++++++++++++++++++++++++++          | 78% ~24s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~23s          
   |++++++++++++++++++++++++++++++++++++++++         | 80% ~22s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~21s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~19s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++++    | 90% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~07s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 51s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~03m 31s      
   |++                                                | 2 % ~03m 31s      
   |++                                                | 3 % ~03m 35s      
   |+++                                               | 4 % ~03m 35s      
   |+++                                               | 5 % ~03m 30s      
   |++++                                              | 6 % ~03m 26s      
   |++++                                              | 7 % ~03m 23s      
   |+++++                                             | 8 % ~03m 20s      
   |+++++                                             | 9 % ~03m 18s      
   |++++++                                            | 10% ~03m 15s      
   |++++++                                            | 11% ~03m 13s      
   |+++++++                                           | 12% ~03m 11s      
   |+++++++                                           | 13% ~03m 08s      
   |++++++++                                          | 14% ~03m 06s      
   |++++++++                                          | 15% ~03m 03s      
   |+++++++++                                         | 16% ~03m 02s      
   |+++++++++                                         | 17% ~02m 59s      
   |++++++++++                                        | 18% ~02m 57s      
   |++++++++++                                        | 19% ~02m 54s      
   |+++++++++++                                       | 20% ~02m 52s      
   |+++++++++++                                       | 21% ~02m 50s      
   |++++++++++++                                      | 22% ~02m 48s      
   |++++++++++++                                      | 23% ~02m 46s      
   |+++++++++++++                                     | 24% ~02m 43s      
   |+++++++++++++                                     | 25% ~02m 41s      
   |++++++++++++++                                    | 26% ~02m 39s      
   |++++++++++++++                                    | 27% ~02m 37s      
   |+++++++++++++++                                   | 28% ~02m 35s      
   |+++++++++++++++                                   | 29% ~02m 33s      
   |++++++++++++++++                                  | 30% ~02m 31s      
   |++++++++++++++++                                  | 31% ~02m 29s      
   |+++++++++++++++++                                 | 32% ~02m 27s      
   |+++++++++++++++++                                 | 33% ~02m 24s      
   |++++++++++++++++++                                | 34% ~02m 22s      
   |++++++++++++++++++                                | 35% ~02m 20s      
   |+++++++++++++++++++                               | 36% ~02m 18s      
   |+++++++++++++++++++                               | 37% ~02m 16s      
   |++++++++++++++++++++                              | 38% ~02m 14s      
   |++++++++++++++++++++                              | 39% ~02m 12s      
   |+++++++++++++++++++++                             | 40% ~02m 09s      
   |+++++++++++++++++++++                             | 41% ~02m 08s      
   |++++++++++++++++++++++                            | 42% ~02m 05s      
   |++++++++++++++++++++++                            | 43% ~02m 04s      
   |+++++++++++++++++++++++                           | 44% ~02m 02s      
   |+++++++++++++++++++++++                           | 45% ~01m 60s      
   |++++++++++++++++++++++++                          | 46% ~01m 58s      
   |++++++++++++++++++++++++                          | 47% ~01m 57s      
   |+++++++++++++++++++++++++                         | 48% ~01m 54s      
   |+++++++++++++++++++++++++                         | 49% ~01m 52s      
   |++++++++++++++++++++++++++                        | 51% ~01m 50s      
   |++++++++++++++++++++++++++                        | 52% ~01m 48s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 45s      
   |+++++++++++++++++++++++++++                       | 54% ~01m 43s      
   |++++++++++++++++++++++++++++                      | 55% ~01m 41s      
   |++++++++++++++++++++++++++++                      | 56% ~01m 38s      
   |+++++++++++++++++++++++++++++                     | 57% ~01m 36s      
   |+++++++++++++++++++++++++++++                     | 58% ~01m 34s      
   |++++++++++++++++++++++++++++++                    | 59% ~01m 32s      
   |++++++++++++++++++++++++++++++                    | 60% ~01m 29s      
   |+++++++++++++++++++++++++++++++                   | 61% ~01m 27s      
   |+++++++++++++++++++++++++++++++                   | 62% ~01m 25s      
   |++++++++++++++++++++++++++++++++                  | 63% ~01m 22s      
   |++++++++++++++++++++++++++++++++                  | 64% ~01m 20s      
   |+++++++++++++++++++++++++++++++++                 | 65% ~01m 18s      
   |+++++++++++++++++++++++++++++++++                 | 66% ~01m 16s      
   |++++++++++++++++++++++++++++++++++                | 67% ~01m 13s      
   |++++++++++++++++++++++++++++++++++                | 68% ~01m 11s      
   |+++++++++++++++++++++++++++++++++++               | 69% ~01m 09s      
   |+++++++++++++++++++++++++++++++++++               | 70% ~01m 07s      
   |++++++++++++++++++++++++++++++++++++              | 71% ~01m 04s      
   |++++++++++++++++++++++++++++++++++++              | 72% ~01m 02s      
   |+++++++++++++++++++++++++++++++++++++             | 73% ~60s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~58s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~55s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~53s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~51s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~49s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~47s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~44s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~42s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~40s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~38s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~35s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~33s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~31s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~29s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~27s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~24s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~22s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 03m 38s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~02m 27s      
   |++                                                | 2 % ~02m 23s      
   |++                                                | 3 % ~02m 26s      
   |+++                                               | 4 % ~02m 32s      
   |+++                                               | 5 % ~02m 28s      
   |++++                                              | 6 % ~02m 25s      
   |++++                                              | 7 % ~02m 23s      
   |+++++                                             | 8 % ~02m 20s      
   |+++++                                             | 9 % ~02m 18s      
   |++++++                                            | 10% ~02m 17s      
   |++++++                                            | 11% ~02m 15s      
   |+++++++                                           | 12% ~02m 13s      
   |+++++++                                           | 13% ~02m 11s      
   |++++++++                                          | 14% ~02m 10s      
   |++++++++                                          | 15% ~02m 08s      
   |+++++++++                                         | 16% ~02m 07s      
   |+++++++++                                         | 17% ~02m 05s      
   |++++++++++                                        | 18% ~02m 03s      
   |++++++++++                                        | 19% ~02m 01s      
   |+++++++++++                                       | 20% ~01m 60s      
   |+++++++++++                                       | 21% ~01m 58s      
   |++++++++++++                                      | 22% ~01m 57s      
   |++++++++++++                                      | 23% ~01m 55s      
   |+++++++++++++                                     | 24% ~01m 54s      
   |+++++++++++++                                     | 26% ~01m 52s      
   |++++++++++++++                                    | 27% ~01m 51s      
   |++++++++++++++                                    | 28% ~01m 49s      
   |+++++++++++++++                                   | 29% ~01m 48s      
   |+++++++++++++++                                   | 30% ~01m 46s      
   |++++++++++++++++                                  | 31% ~01m 44s      
   |++++++++++++++++                                  | 32% ~01m 43s      
   |+++++++++++++++++                                 | 33% ~01m 41s      
   |+++++++++++++++++                                 | 34% ~01m 40s      
   |++++++++++++++++++                                | 35% ~01m 38s      
   |++++++++++++++++++                                | 36% ~01m 37s      
   |+++++++++++++++++++                               | 37% ~01m 35s      
   |+++++++++++++++++++                               | 38% ~01m 34s      
   |++++++++++++++++++++                              | 39% ~01m 32s      
   |++++++++++++++++++++                              | 40% ~01m 31s      
   |+++++++++++++++++++++                             | 41% ~01m 29s      
   |+++++++++++++++++++++                             | 42% ~01m 28s      
   |++++++++++++++++++++++                            | 43% ~01m 26s      
   |++++++++++++++++++++++                            | 44% ~01m 25s      
   |+++++++++++++++++++++++                           | 45% ~01m 23s      
   |+++++++++++++++++++++++                           | 46% ~01m 22s      
   |++++++++++++++++++++++++                          | 47% ~01m 20s      
   |++++++++++++++++++++++++                          | 48% ~01m 19s      
   |+++++++++++++++++++++++++                         | 49% ~01m 17s      
   |+++++++++++++++++++++++++                         | 50% ~01m 16s      
   |++++++++++++++++++++++++++                        | 51% ~01m 14s      
   |+++++++++++++++++++++++++++                       | 52% ~01m 13s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 11s      
   |++++++++++++++++++++++++++++                      | 54% ~01m 10s      
   |++++++++++++++++++++++++++++                      | 55% ~01m 08s      
   |+++++++++++++++++++++++++++++                     | 56% ~01m 07s      
   |+++++++++++++++++++++++++++++                     | 57% ~01m 05s      
   |++++++++++++++++++++++++++++++                    | 58% ~01m 03s      
   |++++++++++++++++++++++++++++++                    | 59% ~01m 02s      
   |+++++++++++++++++++++++++++++++                   | 60% ~01m 00s      
   |+++++++++++++++++++++++++++++++                   | 61% ~59s          
   |++++++++++++++++++++++++++++++++                  | 62% ~57s          
   |++++++++++++++++++++++++++++++++                  | 63% ~56s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~54s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~53s          
   |++++++++++++++++++++++++++++++++++                | 66% ~51s          
   |++++++++++++++++++++++++++++++++++                | 67% ~50s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~48s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~47s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~45s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~44s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~42s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~41s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~39s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~37s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~36s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~34s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~33s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~31s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~30s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~28s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~26s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~25s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~23s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~22s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~19s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~12s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~03s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02m 32s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~03m 15s      
   |++                                                | 2 % ~03m 14s      
   |++                                                | 3 % ~03m 12s      
   |+++                                               | 4 % ~03m 10s      
   |+++                                               | 5 % ~03m 07s      
   |++++                                              | 6 % ~03m 05s      
   |++++                                              | 7 % ~03m 03s      
   |+++++                                             | 8 % ~03m 02s      
   |+++++                                             | 9 % ~03m 00s      
   |++++++                                            | 10% ~02m 58s      
   |++++++                                            | 11% ~02m 56s      
   |+++++++                                           | 12% ~02m 54s      
   |+++++++                                           | 13% ~02m 52s      
   |++++++++                                          | 14% ~02m 50s      
   |++++++++                                          | 15% ~02m 49s      
   |+++++++++                                         | 16% ~02m 46s      
   |+++++++++                                         | 17% ~02m 45s      
   |++++++++++                                        | 18% ~02m 43s      
   |++++++++++                                        | 19% ~02m 41s      
   |+++++++++++                                       | 20% ~02m 39s      
   |+++++++++++                                       | 21% ~02m 37s      
   |++++++++++++                                      | 22% ~02m 36s      
   |++++++++++++                                      | 23% ~02m 34s      
   |+++++++++++++                                     | 24% ~02m 35s      
   |+++++++++++++                                     | 25% ~02m 33s      
   |++++++++++++++                                    | 26% ~02m 30s      
   |++++++++++++++                                    | 27% ~02m 28s      
   |+++++++++++++++                                   | 28% ~02m 26s      
   |+++++++++++++++                                   | 29% ~02m 24s      
   |++++++++++++++++                                  | 30% ~02m 22s      
   |++++++++++++++++                                  | 31% ~02m 20s      
   |+++++++++++++++++                                 | 32% ~02m 18s      
   |+++++++++++++++++                                 | 33% ~02m 16s      
   |++++++++++++++++++                                | 34% ~02m 13s      
   |++++++++++++++++++                                | 35% ~02m 11s      
   |+++++++++++++++++++                               | 36% ~02m 09s      
   |+++++++++++++++++++                               | 37% ~02m 07s      
   |++++++++++++++++++++                              | 38% ~02m 05s      
   |++++++++++++++++++++                              | 39% ~02m 03s      
   |+++++++++++++++++++++                             | 40% ~02m 01s      
   |+++++++++++++++++++++                             | 41% ~01m 58s      
   |++++++++++++++++++++++                            | 42% ~01m 56s      
   |++++++++++++++++++++++                            | 43% ~01m 54s      
   |+++++++++++++++++++++++                           | 44% ~01m 52s      
   |+++++++++++++++++++++++                           | 45% ~01m 50s      
   |++++++++++++++++++++++++                          | 46% ~01m 48s      
   |++++++++++++++++++++++++                          | 47% ~01m 46s      
   |+++++++++++++++++++++++++                         | 48% ~01m 44s      
   |+++++++++++++++++++++++++                         | 49% ~01m 42s      
   |++++++++++++++++++++++++++                        | 51% ~01m 40s      
   |++++++++++++++++++++++++++                        | 52% ~01m 38s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 36s      
   |+++++++++++++++++++++++++++                       | 54% ~01m 33s      
   |++++++++++++++++++++++++++++                      | 55% ~01m 31s      
   |++++++++++++++++++++++++++++                      | 56% ~01m 29s      
   |+++++++++++++++++++++++++++++                     | 57% ~01m 27s      
   |+++++++++++++++++++++++++++++                     | 58% ~01m 25s      
   |++++++++++++++++++++++++++++++                    | 59% ~01m 23s      
   |++++++++++++++++++++++++++++++                    | 60% ~01m 21s      
   |+++++++++++++++++++++++++++++++                   | 61% ~01m 19s      
   |+++++++++++++++++++++++++++++++                   | 62% ~01m 17s      
   |++++++++++++++++++++++++++++++++                  | 63% ~01m 15s      
   |++++++++++++++++++++++++++++++++                  | 64% ~01m 13s      
   |+++++++++++++++++++++++++++++++++                 | 65% ~01m 11s      
   |+++++++++++++++++++++++++++++++++                 | 66% ~01m 09s      
   |++++++++++++++++++++++++++++++++++                | 67% ~01m 07s      
   |++++++++++++++++++++++++++++++++++                | 68% ~01m 05s      
   |+++++++++++++++++++++++++++++++++++               | 69% ~01m 03s      
   |+++++++++++++++++++++++++++++++++++               | 70% ~01m 01s      
   |++++++++++++++++++++++++++++++++++++              | 71% ~59s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~57s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~55s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~53s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~51s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~49s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~47s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~45s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~43s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~41s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~39s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~37s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~34s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~32s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~30s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~28s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~26s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~24s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~22s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~18s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 03m 19s

Display the top markers you computed above.

tiss.markers %>% group_by(cluster) %>% top_n(20, avg_logFC)

Generate an expression heatmap for given cells and genes. In this case, we are plotting the top 20 markers (or all markers if less than 20) for each cluster.

Assigning cell type identity to clusters

At a coarse level, we can use canonical markers to match the unbiased clustering to known cell types:

0: basal cell of epidermis (CL:0002187) 1: basal cell of epidermis (CL:0002187) 2: proliferating basal cell of epidermis (CL:0002187) 3: differentiated keratinocytes (CL:0000312) 4: differentiating basal cell of epidermis (CL:0002187) 5: suprabasal differentiating keratinocytes (CL:0000312) 6: basal cell of epidermis (CL:0002187) 7: filiform differentiated keratinocytes (CL:0000312)

# stash current cluster IDs
tiss <- StashIdent(object = tiss, save.name = "cluster.ids")
# enumerate current cluster IDs and the labels for them
cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7)
free_cell_ontology_id <- c("basal cell of epidermis", "basal cell of epidermis", "proliferating basal cell of epidermis", "differentiated keratinocyte", "differentiating basal cell of epidermis", "suprabasal differentiating keratinocytes", "basal cell of epidermis", "filiform differentiated keratinocytes" )
cell_ontology_class <- c("CL:0002187", "CL:0002187", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312" )
cell_ontology_id <- c("CL:0002187", "CL:0002187", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312", "CL:0002187", "CL:0000312" )
cell_ontology_class.subcell_ontology_class = paste0(cell_ontology_class,': ', free_cell_ontology_id)
tiss@meta.data[,'cell_ontology_class'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = cell_ontology_class)
tiss@meta.data[,'cell_ontology_id'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = cell_ontology_id)
tiss@meta.data[tiss@cell.names,'cell_ontology_class'] <- as.character(tiss@meta.data$cell_ontology_class)
tiss@meta.data[tiss@cell.names,'cell_ontology_id'] <- as.character(tiss@meta.data$cell_ontology_id)
tiss@meta.data[,'subcell_ontology_class'] <- plyr::mapvalues(x = tiss@meta.data$cluster.ids, from = cluster.ids, to = free_cell_ontology_id)
tiss@meta.data[,'cell_ontology_class.subcell_ontology_class'] <- plyr::mapvalues(x = tiss@meta.data$cluster.ids, from = cluster.ids, to = cell_ontology_class.subcell_ontology_class)
TSNEPlot(object = tiss, do.label = TRUE, pt.size = 0.5, group.by='cell_ontology_class.subcell_ontology_class', label.size = 2)

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = tiss, do.return = TRUE, group.by = "mouse.sex")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(tiss@ident), as.character(tiss@meta.data$plate.barcode))
   
    B002777 B002780 D041894 D041904 D041911
  0      61      52      97      89      92
  1      48       9      68      53      75
  2      86      21      27      45      15
  3      39      14      38      48      39
  4      20       8      45      48      41
  5      10       6      35      35      37
  6       0       4      22       4      38
  7       2       3       6      11       3

Save the Robject for later

When you save the annotated tissue, please give it a name.

filename = here('00_data_ingest', '04_tissue_robj_generated', 
                     paste0("facs", tissue_of_interest, "_seurat_tiss.Robj"))
print(filename)
[1] "/Users/Jintonic/Documents/GitHub/tabula-muris/00_data_ingest/04_tissue_robj_generated/facsTongue_seurat_tiss.Robj"
save(tiss, file=filename)
# To reload a saved object
filename = here('00_data_ingest', '04_tissue_robj_generated', 
                      paste0("facs", tissue_of_interest, "_seurat_tiss.Robj"))
load(file=filename)

Export the final metadata

So that Biohub can easily combine all your cell_ontology_classs, please export them as a simple csv.

head(tiss@meta.data)
filename = here('00_data_ingest', '03_tissue_annotation_csv', 
                     paste0(tissue_of_interest, "_cell_ontology_class.csv"))
write.csv(tiss@meta.data[,c('plate.barcode','cell_ontology_class','cell_ontology_class.subcell_ontology_class')], file=filename)
LS0tCnRpdGxlOiAiVG9uZ3VlIEZBQ1MgTm90ZWJvb2siCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkVudGVyIHRoZSBkaXJlY3Rvcnkgb2YgdGhlIG1hY2EgZm9sZGVyIG9uIHlvdXIgZHJpdmUgYW5kIHRoZSBuYW1lIG9mIHRoZSB0aXNzdWUgeW91IHdhbnQgdG8gYW5hbHl6ZS4KCmBgYHtyfQp0aXNzdWVfb2ZfaW50ZXJlc3QgPSAiVG9uZ3VlIgpgYGAKCkxvYWQgdGhlIHJlcXVpc2l0ZSBwYWNrYWdlcyBhbmQgc29tZSBhZGRpdGlvbmFsIGhlbHBlciBmdW5jdGlvbnMuCgpgYGB7cn0KbGlicmFyeShoZXJlKQpsaWJyYXJ5KHVzZWZ1bCkKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoTWF0cml4KQpsaWJyYXJ5KG9udG9sb2d5SW5kZXgpCmNlbGxfb250b2xvZ3kgPSBnZXRfb250b2xvZ3koJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9vYm9waGVub3R5cGUvY2VsbC1vbnRvbG9neS9tYXN0ZXIvY2wtYmFzaWMub2JvJywgZXh0cmFjdF90YWdzPSdldmVyeXRoaW5nJykKCnZhbGlkYXRlX2NlbGxfb250b2xvZ3kgPSBmdW5jdGlvbihjZWxsX29udG9sb2d5X2NsYXNzKXsKICBpbl9jZWxsX29udG9sb2d5ID0gc2FwcGx5KGNlbGxfb250b2xvZ3lfY2xhc3MsIGZ1bmN0aW9uKHgpIGlzLmVsZW1lbnQoeCwgY2VsbF9vbnRvbG9neSRuYW1lKSkKICBpZiAoIWFsbChpbl9jZWxsX29udG9sb2d5KSkgewogICAgbWVzc2FnZSA9IHBhc3RlMCgnIicsIGNlbGxfb250b2xvZ3lfY2xhc3NbIWluX2NlbGxfb250b2xvZ3ldLCAnIiBpcyBub3QgaW4gdGhlIGNlbGwgb250b2xvZ3kKJykKICAgIHN0b3AobWVzc2FnZSkKICB9Cn0KY29udmVydF90b19jZWxsX29udG9sb2d5X2lkID0gZnVuY3Rpb24oY2VsbF9vbnRvbG9neV9jbGFzcyl7CiAgcmV0dXJuKHNhcHBseShjZWxsX29udG9sb2d5X2NsYXNzLCBmdW5jdGlvbih4KSBhcy52ZWN0b3IoY2VsbF9vbnRvbG9neSRpZFtjZWxsX29udG9sb2d5JG5hbWUgPT0geF0pWzFdKSkKfQoKc2F2ZV9kaXIgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICd0aXNzdWVfcm9iaicpCmBgYAoKCgpgYGB7cn0KIyByZWFkIHRoZSBtZXRhZGF0YSB0byBnZXQgdGhlIHBsYXRlcyB3ZSB3YW50CnBsYXRlX21ldGFkYXRhX2ZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDBfZmFjc19yYXdfZGF0YScsICdtZXRhZGF0YV9GQUNTLmNzdicpCgpwbGF0ZV9tZXRhZGF0YSA8LSByZWFkLmNzdihwbGF0ZV9tZXRhZGF0YV9maWxlbmFtZSwgc2VwPSIsIiwgaGVhZGVyID0gVFJVRSkKY29sbmFtZXMocGxhdGVfbWV0YWRhdGEpWzFdIDwtICJwbGF0ZS5iYXJjb2RlIgpwbGF0ZV9tZXRhZGF0YQpgYGAKClN1YnNldCB0aGUgbWV0YWRhdGEgb24gdGhlIHRpc3N1ZS4KCmBgYHtyfQp0aXNzdWVfcGxhdGVzID0gZmlsdGVyKHBsYXRlX21ldGFkYXRhLCB0aXNzdWUgPT0gdGlzc3VlX29mX2ludGVyZXN0KVssYygncGxhdGUuYmFyY29kZScsJ3Rpc3N1ZScsJ3N1YnRpc3N1ZScsJ21vdXNlLnNleCcsICdtb3VzZS5pZCcpXQp0aXNzdWVfcGxhdGVzCmBgYAoKTG9hZCB0aGUgcmVhZCBjb3VudCBkYXRhLgpgYGB7cn0KI0xvYWQgdGhlIGdlbmUgbmFtZXMgYW5kIHNldCB0aGUgbWV0YWRhdGEgY29sdW1ucyBieSBvcGVuaW5nIHRoZSBmaXJzdCBmaWxlCmZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDBfZmFjc19yYXdfZGF0YScsICdGQUNTJywgcGFzdGUwKHRpc3N1ZV9vZl9pbnRlcmVzdCwgJy1jb3VudHMuY3N2JykpCgpyYXcuZGF0YSA9IHJlYWQuY3N2KGZpbGVuYW1lLCBzZXA9IiwiLCByb3cubmFtZXM9MSkKIyByYXcuZGF0YSA9IGRhdGEuZnJhbWUocm93Lm5hbWVzID0gcm93bmFtZXMocmF3LmRhdGEpKQpjb3JuZXIocmF3LmRhdGEpCmBgYApNYWtlIGEgdmVjdG9yIG9mIHBsYXRlIGJhcmNvZGVzIGZvciBlYWNoIGNlbGwKCmBgYHtyfQpwbGF0ZS5iYXJjb2RlcyA9IGxhcHBseShjb2xuYW1lcyhyYXcuZGF0YSksIGZ1bmN0aW9uKHgpIHN0cnNwbGl0KHN0cnNwbGl0KHgsICJfIilbWzFdXVsxXSwgJy4nLCBmaXhlZD1UUlVFKVtbMV1dWzJdKQpoZWFkKHBsYXRlLmJhcmNvZGVzKQpgYGAKClVzZSBvbmx5IHRoZSBtZXRhZGF0YSByb3dzIGNvcnJlc3BvbmRpbmcgdG8gQmxhZGRlciBwbGF0ZXMuIE1ha2UgYSBwbGF0ZSBiYXJjb2RlIGRhdGFmcmFtZSB0byAiZXhwYW5kIiB0aGUgcGVyLXBsYXRlIG1ldGFkYXRhIHRvIGJlIHBlci1jZWxsLgpgYGB7cn0KYmFyY29kZS5kZiA9IHQuZGF0YS5mcmFtZShhcy5kYXRhLmZyYW1lKHBsYXRlLmJhcmNvZGVzKSkKCnJvd25hbWVzKGJhcmNvZGUuZGYpID0gY29sbmFtZXMocmF3LmRhdGEpCmNvbG5hbWVzKGJhcmNvZGUuZGYpID0gYygncGxhdGUuYmFyY29kZScpCmhlYWQoYmFyY29kZS5kZikKCnJuYW1lcyA9IHJvdy5uYW1lcyhiYXJjb2RlLmRmKQptZXRhLmRhdGEgPC0gbWVyZ2UoYmFyY29kZS5kZiwgcGxhdGVfbWV0YWRhdGEsIGJ5PSdwbGF0ZS5iYXJjb2RlJywgc29ydCA9IEYpCnJvdy5uYW1lcyhtZXRhLmRhdGEpIDwtIHJuYW1lcwoKIyBTb3J0IGNlbGxzIGJ5IHBsYXRlIGJhcmNvZGUgYmVjYXVzZSB0aGF0J3MgaG93IHRoZSBkYXRhIHdhcyBvcmlnaW5hbGx5Cm1ldGEuZGF0YSA9IG1ldGEuZGF0YVtvcmRlcihtZXRhLmRhdGEkcGxhdGUuYmFyY29kZSksIF0KY29ybmVyKG1ldGEuZGF0YSkKcmF3LmRhdGEgPSByYXcuZGF0YVssIHJvd25hbWVzKG1ldGEuZGF0YSldCmNvcm5lcihyYXcuZGF0YSkKYGBgClByb2Nlc3MgdGhlIHJhdyBkYXRhIGFuZCBsb2FkIGl0IGludG8gdGhlIFNldXJhdCBvYmplY3QuCgpgYGB7cn0KIyBGaW5kIEVSQ0MncywgY29tcHV0ZSB0aGUgcGVyY2VudCBFUkNDLCBhbmQgZHJvcCB0aGVtIGZyb20gdGhlIHJhdyBkYXRhLgplcmNjcyA8LSBncmVwKHBhdHRlcm4gPSAiXkVSQ0MtIiwgeCA9IHJvd25hbWVzKHggPSByYXcuZGF0YSksIHZhbHVlID0gVFJVRSkKcGVyY2VudC5lcmNjIDwtIE1hdHJpeDo6Y29sU3VtcyhyYXcuZGF0YVtlcmNjcywgXSkvTWF0cml4Ojpjb2xTdW1zKHJhdy5kYXRhKQplcmNjLmluZGV4IDwtIGdyZXAocGF0dGVybiA9ICJeRVJDQy0iLCB4ID0gcm93bmFtZXMoeCA9IHJhdy5kYXRhKSwgdmFsdWUgPSBGQUxTRSkKcmF3LmRhdGEgPC0gcmF3LmRhdGFbLWVyY2MuaW5kZXgsXQoKIyBDcmVhdGUgdGhlIFNldXJhdCBvYmplY3Qgd2l0aCBhbGwgdGhlIGRhdGEKdGlzcyA8LSBDcmVhdGVTZXVyYXRPYmplY3QocmF3LmRhdGEgPSByYXcuZGF0YSwgcHJvamVjdCA9IHRpc3N1ZV9vZl9pbnRlcmVzdCwgCiAgICAgICAgICAgICAgICAgICAgbWluLmNlbGxzID0gNSwgbWluLmdlbmVzID0gNSkKCnRpc3MgPC0gQWRkTWV0YURhdGEob2JqZWN0ID0gdGlzcywgbWV0YS5kYXRhKQp0aXNzIDwtIEFkZE1ldGFEYXRhKG9iamVjdCA9IHRpc3MsIHBlcmNlbnQuZXJjYywgY29sLm5hbWUgPSAicGVyY2VudC5lcmNjIikKIyBDaGFuZ2UgZGVmYXVsdCBuYW1lIGZvciBzdW1zIG9mIGNvdW50cyBmcm9tIG5VTUkgdG8gblJlYWRzCmNvbG5hbWVzKHRpc3NAbWV0YS5kYXRhKVtjb2xuYW1lcyh0aXNzQG1ldGEuZGF0YSkgPT0gJ25VTUknXSA8LSAnblJlYWRzJwoKIyBDcmVhdGUgbWV0YWRhdGEgY29sdW1ucyBmb3IgY2VsbF9vbnRvbG9neV9jbGFzc3MgYW5kIHN1YmNlbGxfb250b2xvZ3lfY2xhc3NzCnRpc3NAbWV0YS5kYXRhWywnY2VsbF9vbnRvbG9neV9jbGFzcyddIDwtIE5BCnRpc3NAbWV0YS5kYXRhWywnc3ViY2VsbF9vbnRvbG9neV9jbGFzcyddIDwtIE5BCmBgYAoKCkNhbGN1bGF0ZSBwZXJjZW50IHJpYm9zb21hbCBnZW5lcy4KCmBgYHtyfQpyaWJvLmdlbmVzIDwtIGdyZXAocGF0dGVybiA9ICJeUnBbc2xdW1s6ZGlnaXQ6XV0iLCB4ID0gcm93bmFtZXMoeCA9IHRpc3NAZGF0YSksIHZhbHVlID0gVFJVRSkKcGVyY2VudC5yaWJvIDwtIE1hdHJpeDo6Y29sU3Vtcyh0aXNzQHJhdy5kYXRhW3JpYm8uZ2VuZXMsIF0pL01hdHJpeDo6Y29sU3Vtcyh0aXNzQHJhdy5kYXRhKQp0aXNzIDwtIEFkZE1ldGFEYXRhKG9iamVjdCA9IHRpc3MsIG1ldGFkYXRhID0gcGVyY2VudC5yaWJvLCBjb2wubmFtZSA9ICJwZXJjZW50LnJpYm8iKQpgYGAKCkEgc2FuaXR5IGNoZWNrOiBnZW5lcyBwZXIgY2VsbCB2cyByZWFkcyBwZXIgY2VsbC4KCmBgYHtyfQpHZW5lUGxvdChvYmplY3QgPSB0aXNzLCBnZW5lMSA9ICJuUmVhZHMiLCBnZW5lMiA9ICJuR2VuZSIsIHVzZS5yYXc9VCkKYGBgCgpGaWx0ZXIgb3V0IGNlbGxzIHdpdGggZmV3IHJlYWRzIGFuZCBmZXcgZ2VuZXMuCgpgYGB7cn0KdGlzcyA8LSBGaWx0ZXJDZWxscyhvYmplY3QgPSB0aXNzLCBzdWJzZXQubmFtZXMgPSBjKCJuR2VuZSIsICJuUmVhZHMiKSwgCiAgICBsb3cudGhyZXNob2xkcyA9IGMoNTAwLCA1MDAwMCksIGhpZ2gudGhyZXNob2xkcyA9IGMoMjUwMDAsIDIwMDAwMDApKQpgYGAKCgpOb3JtYWxpemUgdGhlIGRhdGEsIHRoZW4gcmVncmVzcyBvdXQgY29ycmVsYXRpb24gd2l0aCB0b3RhbCByZWFkcwpgYGB7cn0KdGlzcyA8LSBOb3JtYWxpemVEYXRhKG9iamVjdCA9IHRpc3MsIHNjYWxlLmZhY3RvciA9IDFlNikKdGlzcyA8LSBTY2FsZURhdGEob2JqZWN0ID0gdGlzcykKdGlzcyA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSB0aXNzLCBkby5wbG90ID0gVFJVRSwgeC5oaWdoLmN1dG9mZiA9IEluZiwgeS5jdXRvZmYgPSAwLjUpCmBgYAoKClJ1biBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzLgpgYGB7cn0KdGlzcyA8LSBSdW5QQ0Eob2JqZWN0ID0gdGlzcywgZG8ucHJpbnQgPSBGQUxTRSkKdGlzcyA8LSBQcm9qZWN0UENBKG9iamVjdCA9IHRpc3MsIGRvLnByaW50ID0gRkFMU0UpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MTYsIGZpZy53aWR0aD04fQpQQ0hlYXRtYXAob2JqZWN0ID0gdGlzcywgcGMudXNlID0gMToxMCwgY2VsbHMudXNlID0gNTAwLCBkby5iYWxhbmNlZCA9IFRSVUUsIAogICAgbGFiZWwuY29sdW1ucyA9IEZBTFNFLCB1c2UuZnVsbCA9IEZBTFNFKQpgYGAKCkxhdGVyIG9uIChpbiBGaW5kQ2x1c3RlcnMgYW5kIFRTTkUpIHlvdSB3aWxsIHBpY2sgYSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGtlZXBpbmcgdGhlIG1ham9yIGRpcmVjdGlvbnMgb2YgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGFuZCwgaWRlYWxseSwgc3VwcmVzc2luZyBub2lzZS4gVGhlcmUgaXMgbm8gY29ycmVjdCBhbnN3ZXIgdG8gdGhlIG51bWJlciB0byB1c2UsIGJ1dCBhIGRlY2VudCBydWxlIG9mIHRodW1iIGlzIHRvIGdvIHVudGlsIHRoZSBwbG90IHBsYXRlYXVzLgoKYGBge3J9ClBDRWxib3dQbG90KG9iamVjdCA9IHRpc3MpCmBgYAoKQ2hvb3NlIHRoZSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLgpgYGB7cn0KIyBTZXQgbnVtYmVyIG9mIHByaW5jaXBhbCBjb21wb25lbnRzLiAKbi5wY3MgPSAxMApgYGAKCgpUaGUgY2x1c3RlcmluZyBpcyBwZXJmb3JtZWQgYmFzZWQgb24gYSBuZWFyZXN0IG5laWdoYm9ycyBncmFwaC4gQ2VsbHMgdGhhdCBoYXZlIHNpbWlsYXIgZXhwcmVzc2lvbiB3aWxsIGJlIGpvaW5lZCB0b2dldGhlci4gVGhlIExvdXZhaW4gYWxnb3JpdGhtIGxvb2tzIGZvciBncm91cHMgb2YgY2VsbHMgd2l0aCBoaWdoIG1vZHVsYXJpdHktLW1vcmUgY29ubmVjdGlvbnMgd2l0aGluIHRoZSBncm91cCB0aGFuIGJldHdlZW4gZ3JvdXBzLiBUaGUgcmVzb2x1dGlvbiBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB0aGUgc2NhbGUuLi5oaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgbW9yZSBjbHVzdGVycywgbG93ZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgZmV3ZXIuCgpGb3IgdGhlIHRvcC1sZXZlbCBjbHVzdGVyaW5nLCBhaW0gdG8gdW5kZXItY2x1c3RlciBpbnN0ZWFkIG9mIG92ZXItY2x1c3Rlci4gSXQgd2lsbCBiZSBlYXN5IHRvIHN1YnNldCBncm91cHMgYW5kIGZ1cnRoZXIgYW5hbHl6ZSB0aGVtIGJlbG93LgoKYGBge3J9CiMgU2V0IHJlc29sdXRpb24gCnJlcy51c2VkIDwtIDAuNwoKdGlzcyA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gdGlzcywgcmVkdWN0aW9uLnR5cGUgPSAicGNhIiwgZGltcy51c2UgPSAxOm4ucGNzLCAKICAgIHJlc29sdXRpb24gPSByZXMudXNlZCwgcHJpbnQub3V0cHV0ID0gMCwgc2F2ZS5TTk4gPSBUUlVFLCBmb3JjZS5yZWNhbGMgPSBUUlVFKQpgYGAKClRvIHZpc3VhbGl6ZSAKYGBge3J9CiMgSWYgY2VsbHMgYXJlIHRvbyBzcHJlYWQgb3V0LCB5b3UgY2FuIHJhaXNlIHRoZSBwZXJwbGV4aXR5LiBJZiB5b3UgaGF2ZSBmZXcgY2VsbHMsIHRyeSBhIGxvd2VyIHBlcnBsZXhpdHkgKGJ1dCBuZXZlciBsZXNzIHRoYW4gMTApLgp0aXNzIDwtIFJ1blRTTkUob2JqZWN0ID0gdGlzcywgZGltcy51c2UgPSAxOm4ucGNzLCBzZWVkLnVzZSA9IDIwLCBwZXJwbGV4aXR5PTQwKQojIG5vdGUgdGhhdCB5b3UgY2FuIHNldCBkby5sYWJlbD1UIHRvIGhlbHAgbGFiZWwgaW5kaXZpZHVhbCBjbHVzdGVycwpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5sYWJlbCA9IFQsIHB0LnNpemUgPSAxLjIsIGxhYmVsLnNpemUgPSA0KQoKYGBgCgoKQ2hlY2sgZXhwcmVzc2lvbiBvZiBnZW5lcyBvZiBpbnRlcnNldC4KCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTE2LCBmaWcud2lkdGg9MTB9CmdlbmVzX3RvX2NoZWNrID0gYygnSXRnYjQnLCAnSXRnYTYnLCAnSXRnYjEnLCAnQ2RoMycsICdUb3AyYScsICdNdDInLCAnS3J0MTUnLCAnS3J0NScsICdLcnQxNCcsICdTYnNuJywgJ0tydDEwJywnS2xmNCcKLCAnS3J0ODQnLCAnS3J0MzYnLCAnSG94YzEzJywgJ0tydDQnLCAnS3J0MTMnLCAnRmFicDUnLCAnS3J0MzInLCAgJ0tydDc4JywgJ1ZpbScsICdIaGlwJywgJ1B0Y2gxJywgJ0dsaTEnLCdEc2MxJywgJ0RjbicsICdSdW54MicsICdTb3gyJywgJ1BheDknKQoKRmVhdHVyZVBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2ssIHB0LnNpemUgPSAxLjIsIG5Db2wgPSA0KQpgYGAKCkRvdHBsb3RzIGxldCB5b3Ugc2VlIHRoZSBpbnRlbnNpdHkgb2YgZXhwcHJlc3Npb24gYW5kIHRoZSBmcmFjdGlvbiBvZiBjZWxscyBleHByZXNzaW5nIGZvciBlYWNoIG9mIHlvdXIgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9MjB9CiMgVG8gY2hhbmdlIHRoZSB5LWF4aXMgdG8gc2hvdyByYXcgY291bnRzLCBhZGQgdXNlLnJhdyA9IFQuCkRvdFBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2ssIHBsb3QubGVnZW5kID0gVCkKYGBgCgpIb3cgYmlnIGFyZSB0aGUgY2x1c3RlcnM/CmBgYHtyfQp0YWJsZSh0aXNzQGlkZW50KQpgYGAKCmBgYHtyfQp0aXNzMT1CdWlsZENsdXN0ZXJUcmVlKHRpc3MpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MjAsIGZpZy53aWR0aD0yMH0KIyBUbyBjaGFuZ2UgdGhlIHktYXhpcyB0byBzaG93IHJhdyBjb3VudHMsIGFkZCB1c2UucmF3ID0gVC4KVmxuUGxvdCh0aXNzLCBnZW5lc190b19jaGVjaykKYGBgCgpXaGljaCBtYXJrZXJzIGlkZW50aWZ5IGEgc3BlY2lmaWMgY2x1c3Rlcj8KCmBgYHtyfQojY2x1c3RlcjEubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSB0aXNzLCBpZGVudC4xID0gMSwgbWluLnBjdCA9IDAuMjUsIG9ubHkucG9zID0gVFJVRSwgdGhyZXNoLnVzZSA9IDAuMjUpCiNjbHVzdGVyMi5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKG9iamVjdCA9IHRpc3MsIGlkZW50LjEgPSAyLCBtaW4ucGN0ID0gMC4yNSwgb25seS5wb3MgPSBUUlVFLCB0aHJlc2gudXNlID0gMC4yNSkKI2NsdXN0ZXIzLm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDMsIG1pbi5wY3QgPSAwLjI1LCBvbmx5LnBvcyA9IFRSVUUsIHRocmVzaC51c2UgPSAwLjI1KQojY2x1c3RlcjQubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSB0aXNzLCBpZGVudC4xID0gNCwgbWluLnBjdCA9IDAuMjUsIG9ubHkucG9zID0gVFJVRSwgdGhyZXNoLnVzZSA9IDAuMjUpCiNjbHVzdGVyNS5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKG9iamVjdCA9IHRpc3MsIGlkZW50LjEgPSA1LCBtaW4ucGN0ID0gMC4yNSwgb25seS5wb3MgPSBUUlVFLCB0aHJlc2gudXNlID0gMC4yNSkKI2NsdXN0ZXI2Lm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDYsIG1pbi5wY3QgPSAwLjI1LCBvbmx5LnBvcyA9IFRSVUUsIHRocmVzaC51c2UgPSAwLjI1KQpjbHVzdGVyNy5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKG9iamVjdCA9IHRpc3MsIGlkZW50LjEgPSA2LCBtaW4ucGN0ID0gMC4yNSwgb25seS5wb3MgPSBUUlVFLCB0aHJlc2gudXNlID0gMC4yNSkKI2NsdXN0ZXIwLm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDAsIG1pbi5wY3QgPSAwLjI1LCBvbmx5LnBvcyA9IFRSVUUsIHRocmVzaC51c2UgPSAwLjI1KQpgYGAKCmBgYHtyfQpwcmludCh4ID0gaGVhZCh4ID0gY2x1c3RlcjYubWFya2VycywgbiA9IDMwKSkKYGBgCgpZb3UgY2FuIGFsc28gY29tcHV0ZSBhbGwgbWFya2VycyBmb3IgYWxsIGNsdXN0ZXJzIGF0IG9uY2UuIFRoaXMgbWF5IHRha2Ugc29tZSB0aW1lLgpgYGB7cn0KdGlzcy5tYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKG9iamVjdCA9IHRpc3MsIG9ubHkucG9zID0gVFJVRSwgbWluLnBjdCA9IDAuMjUsIHRocmVzaC51c2UgPSAwLjI1KQpgYGAKCkRpc3BsYXkgdGhlIHRvcCBtYXJrZXJzIHlvdSBjb21wdXRlZCBhYm92ZS4KYGBge3J9CnRpc3MubWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKDIwLCBhdmdfbG9nRkMpCmBgYAoKIyMgR2VuZXJhdGUgYW4gZXhwcmVzc2lvbiBoZWF0bWFwIGZvciBnaXZlbiBjZWxscyBhbmQgZ2VuZXMuIEluIHRoaXMgY2FzZSwgd2UgYXJlIHBsb3R0aW5nIHRoZSB0b3AgMjAgbWFya2VycyAob3IgYWxsIG1hcmtlcnMgaWYgbGVzcyB0aGFuIDIwKSBmb3IgZWFjaCBjbHVzdGVyLgoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NTAsIGZpZy53aWR0aD0zNX0KI3RvcDEwIDwtIHRpc3MubWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKDEwLCBhdmdfbG9nRkMpCnRvcDIwIDwtIHRpc3MubWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKDIwLCBhdmdfbG9nRkMpCiMgc2V0dGluZyBzbGltLmNvbC5sYWJlbCB0byBUUlVFIHdpbGwgcHJpbnQganVzdCB0aGUgY2x1c3RlciBJRFMgaW5zdGVhZCBvZgojIGV2ZXJ5IGNlbGwgbmFtZQpEb0hlYXRtYXAodGlzcywgZ2VuZXMudXNlID0gdG9wMjAkZ2VuZSwgc2xpbS5jb2wubGFiZWwgPSBUUlVFLCByZW1vdmUua2V5ID0gVFJVRSwgY2V4LnJvdyA9IDIwLCBncm91cC5jZXggPSAyMCApCmBgYAojIyBBc3NpZ25pbmcgY2VsbCB0eXBlIGlkZW50aXR5IHRvIGNsdXN0ZXJzCgpBdCBhIGNvYXJzZSBsZXZlbCwgd2UgY2FuIHVzZSBjYW5vbmljYWwgbWFya2VycyB0byBtYXRjaCB0aGUgdW5iaWFzZWQgY2x1c3RlcmluZyB0byBrbm93biBjZWxsIHR5cGVzOgoKMDogYmFzYWwgY2VsbCBvZiBlcGlkZXJtaXMgKENMOjAwMDIxODcpCjE6IGJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIChDTDowMDAyMTg3KQoyOiBwcm9saWZlcmF0aW5nIGJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIChDTDowMDAyMTg3KQozOiBkaWZmZXJlbnRpYXRlZCBrZXJhdGlub2N5dGVzIChDTDowMDAwMzEyKQo0OiBkaWZmZXJlbnRpYXRpbmcgYmFzYWwgY2VsbCBvZiBlcGlkZXJtaXMgKENMOjAwMDIxODcpCjU6IHN1cHJhYmFzYWwgZGlmZmVyZW50aWF0aW5nIGtlcmF0aW5vY3l0ZXMgIChDTDowMDAwMzEyKQo2OiBiYXNhbCBjZWxsIG9mIGVwaWRlcm1pcyAoQ0w6MDAwMjE4NykKNzogZmlsaWZvcm0gZGlmZmVyZW50aWF0ZWQga2VyYXRpbm9jeXRlcyAoQ0w6MDAwMDMxMikKCmBgYHtyfQojIHN0YXNoIGN1cnJlbnQgY2x1c3RlciBJRHMKdGlzcyA8LSBTdGFzaElkZW50KG9iamVjdCA9IHRpc3MsIHNhdmUubmFtZSA9ICJjbHVzdGVyLmlkcyIpCgojIGVudW1lcmF0ZSBjdXJyZW50IGNsdXN0ZXIgSURzIGFuZCB0aGUgbGFiZWxzIGZvciB0aGVtCmNsdXN0ZXIuaWRzIDwtIGMoMCwgMSwgMiwgMywgNCwgNSwgNiwgNykKZnJlZV9jZWxsX29udG9sb2d5X2lkIDwtIGMoImJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIiwgImJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIiwgInByb2xpZmVyYXRpbmcgYmFzYWwgY2VsbCBvZiBlcGlkZXJtaXMiLCAiZGlmZmVyZW50aWF0ZWQga2VyYXRpbm9jeXRlIiwgImRpZmZlcmVudGlhdGluZyBiYXNhbCBjZWxsIG9mIGVwaWRlcm1pcyIsICJzdXByYWJhc2FsIGRpZmZlcmVudGlhdGluZyBrZXJhdGlub2N5dGVzIiwgImJhc2FsIGNlbGwgb2YgZXBpZGVybWlzIiwgImZpbGlmb3JtIGRpZmZlcmVudGlhdGVkIGtlcmF0aW5vY3l0ZXMiICkKCmNlbGxfb250b2xvZ3lfY2xhc3MgPC0gYygiQ0w6MDAwMjE4NyIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDIxODciLCAiQ0w6MDAwMDMxMiIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDAzMTIiLCAiQ0w6MDAwMjE4NyIsICJDTDowMDAwMzEyIiApCmNlbGxfb250b2xvZ3lfaWQgPC0gYygiQ0w6MDAwMjE4NyIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDIxODciLCAiQ0w6MDAwMDMxMiIsICJDTDowMDAyMTg3IiwgIkNMOjAwMDAzMTIiLCAiQ0w6MDAwMjE4NyIsICJDTDowMDAwMzEyIiApCgpjZWxsX29udG9sb2d5X2NsYXNzLnN1YmNlbGxfb250b2xvZ3lfY2xhc3MgPSBwYXN0ZTAoY2VsbF9vbnRvbG9neV9jbGFzcywnOiAnLCBmcmVlX2NlbGxfb250b2xvZ3lfaWQpCgp0aXNzQG1ldGEuZGF0YVssJ2NlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBwbHlyOjptYXB2YWx1ZXMoeCA9IHRpc3NAaWRlbnQsIGZyb20gPSBjbHVzdGVyLmlkcywgdG8gPSBjZWxsX29udG9sb2d5X2NsYXNzKQp0aXNzQG1ldGEuZGF0YVssJ2NlbGxfb250b2xvZ3lfaWQnXSA8LSBwbHlyOjptYXB2YWx1ZXMoeCA9IHRpc3NAaWRlbnQsIGZyb20gPSBjbHVzdGVyLmlkcywgdG8gPSBjZWxsX29udG9sb2d5X2lkKQoKdGlzc0BtZXRhLmRhdGFbdGlzc0BjZWxsLm5hbWVzLCdjZWxsX29udG9sb2d5X2NsYXNzJ10gPC0gYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJGNlbGxfb250b2xvZ3lfY2xhc3MpCnRpc3NAbWV0YS5kYXRhW3Rpc3NAY2VsbC5uYW1lcywnY2VsbF9vbnRvbG9neV9pZCddIDwtIGFzLmNoYXJhY3Rlcih0aXNzQG1ldGEuZGF0YSRjZWxsX29udG9sb2d5X2lkKQoKdGlzc0BtZXRhLmRhdGFbLCdzdWJjZWxsX29udG9sb2d5X2NsYXNzJ10gPC0gcGx5cjo6bWFwdmFsdWVzKHggPSB0aXNzQG1ldGEuZGF0YSRjbHVzdGVyLmlkcywgZnJvbSA9IGNsdXN0ZXIuaWRzLCB0byA9IGZyZWVfY2VsbF9vbnRvbG9neV9pZCkKdGlzc0BtZXRhLmRhdGFbLCdjZWxsX29udG9sb2d5X2NsYXNzLnN1YmNlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBwbHlyOjptYXB2YWx1ZXMoeCA9IHRpc3NAbWV0YS5kYXRhJGNsdXN0ZXIuaWRzLCBmcm9tID0gY2x1c3Rlci5pZHMsIHRvID0gY2VsbF9vbnRvbG9neV9jbGFzcy5zdWJjZWxsX29udG9sb2d5X2NsYXNzKQoKClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLmxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDAuNSwgZ3JvdXAuYnk9J2NlbGxfb250b2xvZ3lfY2xhc3Muc3ViY2VsbF9vbnRvbG9neV9jbGFzcycsIGxhYmVsLnNpemUgPSAyKQpgYGAKCgojIyBDaGVja2luZyBmb3IgYmF0Y2ggZWZmZWN0cwoKCkNvbG9yIGJ5IG1ldGFkYXRhLCBsaWtlIHBsYXRlIGJhcmNvZGUsIHRvIGNoZWNrIGZvciBiYXRjaCBlZmZlY3RzLgpgYGB7cn0KVFNORVBsb3Qob2JqZWN0ID0gdGlzcywgZG8ucmV0dXJuID0gVFJVRSwgZ3JvdXAuYnkgPSAibW91c2Uuc2V4IikKYGBgCgpQcmludCBhIHRhYmxlIHNob3dpbmcgdGhlIGNvdW50IG9mIGNlbGxzIGluIGVhY2ggaWRlbnRpdHkgY2F0ZWdvcnkgZnJvbSBlYWNoIHBsYXRlLgoKYGBge3J9CnRhYmxlKGFzLmNoYXJhY3Rlcih0aXNzQGlkZW50KSwgYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJHBsYXRlLmJhcmNvZGUpKQpgYGAKCgoKIyBTYXZlIHRoZSBSb2JqZWN0IGZvciBsYXRlcgpXaGVuIHlvdSBzYXZlIHRoZSBhbm5vdGF0ZWQgdGlzc3VlLCBwbGVhc2UgZ2l2ZSBpdCBhIG5hbWUuCgpgYGB7cn0KZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICcwNF90aXNzdWVfcm9ial9nZW5lcmF0ZWQnLCAKICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCJmYWNzIiwgdGlzc3VlX29mX2ludGVyZXN0LCAiX3NldXJhdF90aXNzLlJvYmoiKSkKcHJpbnQoZmlsZW5hbWUpCnNhdmUodGlzcywgZmlsZT1maWxlbmFtZSkKYGBgCgpgYGB7cn0KIyBUbyByZWxvYWQgYSBzYXZlZCBvYmplY3QKZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICcwNF90aXNzdWVfcm9ial9nZW5lcmF0ZWQnLCAKICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiZmFjcyIsIHRpc3N1ZV9vZl9pbnRlcmVzdCwgIl9zZXVyYXRfdGlzcy5Sb2JqIikpCmxvYWQoZmlsZT1maWxlbmFtZSkKYGBgCgoKCiMgRXhwb3J0IHRoZSBmaW5hbCBtZXRhZGF0YQoKU28gdGhhdCBCaW9odWIgY2FuIGVhc2lseSBjb21iaW5lIGFsbCB5b3VyIGNlbGxfb250b2xvZ3lfY2xhc3NzLCBwbGVhc2UgZXhwb3J0IHRoZW0gYXMgYSBzaW1wbGUgY3N2LgoKYGBge3J9CmhlYWQodGlzc0BtZXRhLmRhdGEpCmBgYAoKCmBgYHtyfQpmaWxlbmFtZSA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJzAzX3Rpc3N1ZV9hbm5vdGF0aW9uX2NzdicsIAogICAgICAgICAgICAgICAgICAgICBwYXN0ZTAodGlzc3VlX29mX2ludGVyZXN0LCAiX2NlbGxfb250b2xvZ3lfY2xhc3MuY3N2IikpCndyaXRlLmNzdih0aXNzQG1ldGEuZGF0YVssYygncGxhdGUuYmFyY29kZScsJ2NlbGxfb250b2xvZ3lfY2xhc3MnLCdjZWxsX29udG9sb2d5X2NsYXNzLnN1YmNlbGxfb250b2xvZ3lfY2xhc3MnKV0sIGZpbGU9ZmlsZW5hbWUpCmBgYAoKCg==